package service

import (
	"errors"
	"fmt"
	"github.com/mosongcc/gotool/gtime"
	"gorm.io/gorm"
	"time"
	"vitepress-serve/internal/model"
)

type OrderService struct {
	*Service
}

func NewOrderService(db *gorm.DB) *OrderService {
	return &OrderService{
		Service: &Service{db: db},
	}
}

// FinishVip 订单完成/订单发货
func (service *OrderService) FinishVip(orderId string) (order model.Order, err error) {
	if err = service.db.Where("order_id = ?", orderId).Take(&order).Error; err != nil {
		return
	}
	if order.Status != model.ORDER_PAYSUC {
		err = errors.New("发货失败，当前非待发货状态")
		return
	}

	var user model.User
	if err = service.db.Where("uid = ?", order.Uid).Take(&user).Error; err != nil {
		return
	}

	var vip_date = time.Now()
	if user.Type == model.USER_TYPE_VIP && len(user.VipDate) == 8 {
		vip_date = gtime.ParseT8(user.VipDate)
	}

	switch order.ProdType {
	case model.ProductType_VIP_DAYS:
		vip_date = vip_date.AddDate(0, 0, 1)
	case model.ProductType_VIP_MONTH:
		vip_date = vip_date.AddDate(0, 1, 1)
	case model.ProductType_VIP_YEAR:
		vip_date = vip_date.AddDate(1, 0, 1)
	case model.ProductType_VIP_LONG:
		vip_date = vip_date.AddDate(100, 0, 1)
	default:
		err = errors.New("发货失败，未知产品类型")
		return
	}

	// 事务更新订单状态与用户会员有效期
	err = service.db.Transaction(func(tx *gorm.DB) (err error) {
		order.Status = model.ORDER_FINISH
		order.FinishTime = gtime.NowF14()
		order.Mtime = gtime.NowF14()
		ors := tx.Model(&order).Where("order_id = ? and status = ?", orderId, model.ORDER_PAYSUC).Updates(order)
		if ors.Error != nil {
			err = fmt.Errorf("ORDER_FINISH_ERROR: Order %s ", ors.Error.Error())
			return
		}
		if ors.RowsAffected != 1 {
			err = fmt.Errorf("ORDER_FINISH_ERROR: Order RowsAffected=%v ", ors.RowsAffected)
			return
		}

		user.Type = model.USER_TYPE_VIP
		user.VipDate = vip_date.Format(gtime.LayoutT8)
		user.Mtime = gtime.NowF14()
		urs := tx.Model(&user).Where("uid = ?", order.Uid).Updates(user)
		if urs.Error != nil {
			err = fmt.Errorf("ORDER_FINISH_ERROR: User %s ", urs.Error.Error())
			return
		}
		if urs.RowsAffected != 1 {
			err = fmt.Errorf("ORDER_FINISH_ERROR: User RowsAffected=%v ", urs.RowsAffected)
			return
		}
		return
	})
	if err != nil {
		return
	}
	return
}
